#include "cTreeView.h"

cTreeView::cTreeView(cHwnd * hwndParent,int x,int y,int largeur,int hauteur,cHwnd * HWNDParent)
    :cControl(hwndParent)
{
    //ctor

    HWND leParent=hwndParent->getHwnd();
    if(HWNDParent!=NULL)
        leParent=HWNDParent->getHwnd();



    hWnd=CreateWindowEx(0, WC_TREEVIEW,
                            TEXT("Tree View"),
                            WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP| TVS_LINESATROOT |TVS_HASBUTTONS ,
                            x,
                            y,
                            largeur,
                            hauteur,
                            leParent,
                            NULL,
                            hInstance,
                            NULL);
    FinalInit();

    OnSelect=NULL;
    OnClick=NULL;
    OnDbleClick=NULL;

    Node=new cTreeNode(this,TVI_ROOT);

}

cTreeView::~cTreeView()
{
    //dtor
}

bool cTreeView::TraitementEvent(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,LRESULT & resultat)
{
    switch (message)
    {
        case WM_ERASEBKGND:
        {
            break;
        }

        case WM_NOTIFY:
        {
            NMHDR * structnhdr=(NMHDR*)lparam;
            switch(structnhdr->code)
            {
                case NM_CUSTOMDRAW:
                {
                    LPNMTVCUSTOMDRAW lpNMCustomDraw = (LPNMTVCUSTOMDRAW) lparam;
                    switch(lpNMCustomDraw->nmcd.dwDrawStage)
                    {
                        case CDDS_PREPAINT :
                        {
                            resultat = CDRF_NOTIFYITEMDRAW;
                            return true;
                        }

                        case CDDS_ITEMPREPAINT | CDDS_ITEM:
                        {
                            cTreeNode * noeud=(cTreeNode *)lpNMCustomDraw->nmcd.lItemlParam;
                            if(noeud!=NULL)
                            {
                                if( !(lpNMCustomDraw->nmcd.uItemState&CDIS_FOCUS))
                                    lpNMCustomDraw->clrText=noeud->GetTextColor();
                                else
                                    lpNMCustomDraw->clrText=RGB(255,255,255);


                                SelectObject(lpNMCustomDraw->nmcd.hdc,noeud->GetFont());
                                resultat = CDRF_NEWFONT;
                            }
                            else
                                resultat = CDRF_DODEFAULT;
                            return true;
                        }


                    };
                    break;
                }

                case TVN_SELCHANGED:
                {
                    LPNMTREEVIEW itemselect=(LPNMTREEVIEW)lparam;
                    if(OnSelect!=NULL)
                    {
                        cEvent * event=new cEvent(this);
                        (_parent->*OnSelect)(event);
                        delete event;
                        resultat=false;
                        return true;
                    }
                    break;
                }

                case NM_CLICK :
                {
                    LPNMTREEVIEW itemselect=(LPNMTREEVIEW)lparam;
                    if(OnClick!=NULL)
                    {
                        TVHITTESTINFO lpht;
                        GetCursorPos(&lpht.pt);
                        ScreenToClient(this->getHwnd(),&lpht.pt);

                        HTREEITEM item=TreeView_HitTest(this->getHwnd(),&lpht);
                        if(item!=NULL)
                            TreeView_SelectItem(this->getHwnd(),item);


                        cEvent * event=new cEvent(this);
                        (_parent->*OnClick)(event);
                        delete event;
                        resultat=false;
                        return true;
                    }
                    break;
                }

                case NM_DBLCLK:
                {
                    LPNMTREEVIEW itemselect=(LPNMTREEVIEW)lparam;
                    if(OnDbleClick!=NULL)
                    {
                        TVHITTESTINFO lpht;
                        GetCursorPos(&lpht.pt);
                        ScreenToClient(this->getHwnd(),&lpht.pt);

                        HTREEITEM item=TreeView_HitTest(this->getHwnd(),&lpht);
                        if(item!=NULL)
                            TreeView_SelectItem(this->getHwnd(),item);

                        cEvent * event=new cEvent(this);
                        (_parent->*OnDbleClick)(event);
                        delete event;
                        resultat=false;
                        return true;
                    }
                    break;
                }

            };

            break;
        }
    };


    return false;
}

/** @brief GetSelectedNode
  *
  * @todo: document this function
  */
cTreeNode* cTreeView::GetSelectedNode()
{
    HTREEITEM item=TreeView_GetSelection(this->getHwnd());
    TVITEM tvitem;
    tvitem.mask=TVIF_HANDLE|TVIF_PARAM;
    tvitem.hItem=item;
    tvitem.lParam=0;
    TreeView_GetItem(this->getHwnd(),&tvitem);
    return (cTreeNode*)tvitem.lParam;
}



/** @brief Add
  *
  * @todo: document this function
  */
cTreeNode * cTreeNode::Add(string libelle)
{
    char * texte=new char[libelle.size()+1];
    libelle.copy(texte,libelle.size());
    texte[libelle.size()]='\0';
    TVINSERTSTRUCT  additemstruct;
    TVITEM tvi;
    tvi.mask = TVIF_TEXT ;
    tvi.pszText = texte;
    tvi.cchTextMax = strlen(texte)+1;

    additemstruct.hParent=_item;
    additemstruct.hInsertAfter=TVI_LAST;
    additemstruct.item=tvi;

    SendMessage(_treeview->getHwnd(),CCM_SETVERSION,5,0);

    HTREEITEM item= TreeView_InsertItem(_treeview->getHwnd(),&additemstruct);
    TreeView_SetItemState(_treeview->getHwnd(),item,TVIS_EXPANDED,TVIS_EXPANDED);

    delete [] texte;
    return new cTreeNode(_treeview,item);
}

/** @brief cTreeNode
  *
  * @todo: document this function
  */
 cTreeNode::cTreeNode(cTreeView* treeView,HTREEITEM item)
{
    Data=NULL;
    _treeview=treeView;
    _item=item;
    font=(HFONT)SendMessage(_treeview->getHwnd(),WM_GETFONT,0,0);
    SetTextColor(0,0,0);
    if(_item!=TVI_ROOT)
    {
        TVITEM tvitem;
        tvitem.mask=TVIF_HANDLE|TVIF_PARAM;
        tvitem.hItem=_item;
        tvitem.lParam=(LPARAM)this;
        TreeView_SetItem(_treeview->getHwnd(),&tvitem);
    }
}
void cTreeNode::SetFont(LPCSTR familly,int size,int weight,bool italic,bool underline)
{
    HDC hDC=GetDC(NULL);
    int nHeight = -MulDiv(size, GetDeviceCaps(hDC, LOGPIXELSY), 96);
    ReleaseDC(NULL,hDC);

    HFONT nouvellePolice=CreateFont(
        nHeight,	// logical height of font
        0,	// logical average character width
        0,	// angle of escapement
        0,	// base-line orientation angle
        weight,	// font weight
        italic,	// italic attribute flag
        underline,	// underline attribute flag
        false,	// strikeout attribute flag
        DEFAULT_CHARSET,	// character set identifier
        OUT_DEFAULT_PRECIS,	// output precision
        CLIP_DEFAULT_PRECIS,	// clipping precision
        DEFAULT_QUALITY,	// output quality
        DEFAULT_PITCH| FF_SWISS,	// pitch and family
        familly 	// pointer to typeface name string
   );
   this->SetFont(nouvellePolice);
}

void cTreeNode::SetFont(HFONT font)
{
    this->font=font;
}

